// $Id: wfs.c 78 2012-07-20 21:30:18Z alan.watson.f $

#define _POSIX_C_SOURCE 200112L

#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/stat.h>
#include <unistd.h>

#include "oaxaca-config.h"
#include "oaxaca.h"
#include "ids.h"
#include "wfs.h"

////////////////////////////////////////////////////////////////////////////////

int
oaxaca_wfs_initialized(void)
{
  return oaxaca_shm != NULL && oaxaca_shm->wfs.initialized;
}

char
oaxaca_wfs_command(void)
{
  if (oaxaca_shm == NULL)
    return 0;
  else
    return oaxaca_shm->wfs.command;
}

void
oaxaca_wfs_set_command(char command)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.command = command;
}

unsigned long
oaxaca_wfs_cycle(void)
{
  if (oaxaca_shm == NULL)
    return 0;
  else
    return oaxaca_shm->wfs.cycle;
}

double 
oaxaca_wfs_pixelclockfrequency(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.pixelclockfrequency;
}

void 
oaxaca_wfs_set_pixelclockfrequency(double pixelclockfrequency)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.pixelclockfrequency = pixelclockfrequency;
}

int 
oaxaca_wfs_window_sx(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.window.sx;
}

void 
oaxaca_wfs_set_window_sx(int sx)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.window.sx = sx;
}

int 
oaxaca_wfs_window_sy(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.window.sy;
}

void 
oaxaca_wfs_set_window_sy(int sy)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.window.sy = sy;
}

int 
oaxaca_wfs_window_nx(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.window.nx;
}

void 
oaxaca_wfs_set_window_nx(int nx)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.window.nx = nx;
}

int 
oaxaca_wfs_window_ny(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.window.ny;
}

void 
oaxaca_wfs_set_window_ny(int ny)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.window.ny = ny;
}

double 
oaxaca_wfs_minframefrequency(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.minframefrequency;
}

double 
oaxaca_wfs_maxframefrequency(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.maxframefrequency;
}

double 
oaxaca_wfs_framefrequency(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.framefrequency;
}

void 
oaxaca_wfs_set_framefrequency(double framefrequency)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.framefrequency = framefrequency;
}

double 
oaxaca_wfs_exposuretime(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.exposuretime;
}

void 
oaxaca_wfs_set_exposuretime(double exposuretime)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.exposuretime = exposuretime;
}

double 
oaxaca_wfs_aogain(void)
{
  if (oaxaca_shm == NULL)
    return 0.0;
  else
    return oaxaca_shm->wfs.aogain;
}

void 
oaxaca_wfs_set_aogain(double aogain)
{
  if (oaxaca_shm != NULL)
    oaxaca_shm->wfs.aogain = aogain;
}

////////////////////////////////////////////////////////////////////////////////

void
oaxaca_wfs_main(void)
{
  oaxaca_common_main("wfs");
  oaxaca_initialized = &oaxaca_shm->wfs.initialized;
  
  oaxaca_shm->wfs.initialized         = 0;
  oaxaca_shm->wfs.command             = 'i';
  oaxaca_shm->wfs.cycle               = 0;
  oaxaca_shm->wfs.pixelclockfrequency = 48e6;
  oaxaca_shm->wfs.window.sx           = 0;
  oaxaca_shm->wfs.window.sy           = 0;
  oaxaca_shm->wfs.window.nx           = 1280;
  oaxaca_shm->wfs.window.ny           = 1024;
  oaxaca_shm->wfs.framefrequency      = DBL_MAX;
  
  oaxaca_info("initializing wfs hardware.");
  oaxaca_ids_initialize(OAXACA_WFS_IDS_CAMERA_ID);    
  oaxaca_shm->wfs.initialized = 1;
    
  oaxaca_info("starting command loop.");

  for (;;) {
    int command = oaxaca_shm->wfs.command;
    switch (command) {
    case 'i': // start idling
      oaxaca_shm->wfs.command = 'I';
      break;
    case 'I': // continue idling
      break;    
    case 'c': // configure
      oaxaca_ids_configure();
      oaxaca_shm->wfs.command = 'I';
      break;
    case 'e': // loop - expose
      oaxaca_shm->wfs.command = 'E';
      oaxaca_wfs_loop();
      oaxaca_shm->wfs.command = 'I';
      break;
    case 'd': // loop - dark
      oaxaca_shm->wfs.command = 'D';
      oaxaca_wfs_loop();
      oaxaca_shm->wfs.command = 'I';
      break;
    case 'a': // loop - ao
      oaxaca_shm->wfs.command = 'A';
      oaxaca_wfs_loop();
      oaxaca_shm->wfs.command = 'I';
      break;
    default:
      oaxaca_error("unrecognized command \'%c\'.", command);
      break;
    }
    oaxaca_usleep(20);
  }
  
  oaxaca_error("command loop terminated.");
}

////////////////////////////////////////////////////////////////////////////////